package judesart.app.client.artwork;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import judesart.app.domain.Artwork;
import judesart.app.domain.ArtworkType;

import com.extjs.gxt.ui.client.data.ModelData;

public class ArtworkModel implements ModelData
{
    final Artwork data;

    public static enum Prop
    {
        ID, TITLE, DESCRIPTION, YEAR, TYPE, TECHNIC, PHOTO_ID
    }

    public ArtworkModel(final Artwork data)
    {
        this.data = data;
    }

    @Override
    public <X> X get(String property)
    {
        switch (Prop.valueOf(property.toUpperCase()))
        {
        case ID:
            return (X) data.getId();
        case DESCRIPTION:
            return (X) data.getDescription();
        case TECHNIC:
            return (X) data.getTechnic();
        case TITLE:
            return (X) data.getTitle();
        case TYPE:
            return (X) data.getType().name();
        case YEAR:
            return (X) Long.toString(data.getYear());
        case PHOTO_ID:
            if (data.getPhotos() != null && data.getPhotos().size() > 0)
            {
                return (X) data.getPhotos().get(0).getImageId();
            }
        }
        return null;
    }

    @Override
    public Map<String, Object> getProperties()
    {
        Map<String, Object> result = new HashMap<String, Object>();
        for (Prop prop : Prop.values())
        {
            String name = prop.name().toLowerCase();
            result.put(name, get(name));
        }
        return result;
    }

    @Override
    public Collection<String> getPropertyNames()
    {
        Collection<String> result = new ArrayList<String>();
        for (Prop prop : Prop.values())
        {
            result.add(prop.name().toLowerCase());
        }
        return result;
    }

    @Override
    public <X> X remove(String property)
    {
        return (X) set(property, (X) null);
    }

    @Override
    public <X> X set(String property, X value)
    {
        X oldValue;
        switch (Prop.valueOf(property.toUpperCase()))
        {
        case ID:
            oldValue = (X) data.getId();
            data.setId((Long) value);
            break;
        case DESCRIPTION:
            oldValue = (X) data.getDescription();
            data.setDescription((String) value);
            break;
        case TECHNIC:
            oldValue = (X) data.getTechnic();
            data.setTechnic((String) value);
            break;
        case TITLE:
            oldValue = (X) data.getTitle();
            data.setTitle((String) value);
            break;
        case TYPE:
            oldValue = (X) data.getType().name();
            data.setType(ArtworkType.valueOf((String) value));
            break;
        case YEAR:
            oldValue = (X) Long.toString(data.getYear());
            data.setYear(Long.parseLong((String) value));
            break;
        default:
            oldValue = null;
        }
        return oldValue;
    }

    public static List<ArtworkModel> modelsFor(List<Artwork> works)
    {
        List<ArtworkModel> result = new ArrayList<ArtworkModel>();
        for (Artwork artwork : works)
        {
            result.add(new ArtworkModel(artwork));
        }
        return result;
    }
}
